import BaseScene, { SceneConfig } from '../../../components/scenes/BaseScene';
import {
    AdditiveBlending,
    BoxGeometry,
    Color, FrontSide,
    Mesh,
    ShaderMaterial,
    ShapeBufferGeometry,
} from 'three'
import { IUniform } from 'three/src/renderers/shaders/UniformsLib';

class Render extends BaseScene {
  static vertexShader = `
    uniform vec3 viewVector;
    uniform float c;
    uniform float p;
    varying float intensity;
    void main() 
    {
        vec3 vNormal = normalize( normalMatrix * normal );
        vec3 vNormel = normalize( normalMatrix * viewVector );
        intensity = pow( c - dot(vNormal, vNormel), p );
        gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
    }
  `;
  static fragmentShader = `
    uniform vec3 glowColor;
    varying float intensity;
    void main() 
    {
        vec3 glow = glowColor * intensity;
        gl_FragColor = vec4( glow, 1.0 );
    }
  `;
  constructor(config) {
    super(config);
    // this.scene.background = new Color(0xffffff);
    this.addShader();
  }
  private addShader() {
    const c: IUniform = { value: 1.0 };
    const p: IUniform = { value: 1.4 };
    const glowColor = { value: new Color(0xffff00) };
    const viewVector = { type: 'v3', value: this.camera.position };
    const boxGeometry = new BoxGeometry(50, 50, 50);
    const material = new ShaderMaterial({
      uniforms: {
        c,
        p,
        glowColor,
        viewVector,
      },
      fragmentShader: Render.fragmentShader,
      vertexShader: Render.vertexShader,
      side: FrontSide,
      blending: AdditiveBlending,
      transparent: true,
    });
    this.scene.add(new Mesh(boxGeometry, material));
  }
}

export const BasicShaderRender = (config: SceneConfig) => {
  const render = new Render(config);
  render.run();
  return render;
};
